home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1997 April / macformat-049.iso / mac / Shareware Plus / Developers / dropg++ / usr / include / sys / mbuf.h < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-20  |  12.9 KB  |  403 lines  |  [TEXT/R*ch]

  1. /*
  2.  * Copyright (c) 1982, 1986, 1988, 1993
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  *    @(#)mbuf.h    8.3 (Berkeley) 1/21/94
  34.  */
  35.  
  36. #ifndef M_WAITOK
  37. #include <sys/malloc.h>
  38. #endif
  39.  
  40. /*
  41.  * Mbufs are of a single size, MSIZE (machine/machparam.h), which
  42.  * includes overhead.  An mbuf may add a single "mbuf cluster" of size
  43.  * MCLBYTES (also in machine/machparam.h), which has no additional overhead
  44.  * and is used instead of the internal data area; this is done when
  45.  * at least MINCLSIZE of data must be stored.
  46.  */
  47.  
  48. #define    MLEN        (MSIZE - sizeof(struct m_hdr))    /* normal data len */
  49. #define    MHLEN        (MLEN - sizeof(struct pkthdr))    /* data len w/pkthdr */
  50.  
  51. #define    MINCLSIZE    (MHLEN + MLEN)    /* smallest amount to put in cluster */
  52. #define    M_MAXCOMPRESS    (MHLEN / 2)    /* max amount to copy for compression */
  53.  
  54. /*
  55.  * Macros for type conversion
  56.  * mtod(m,t) -    convert mbuf pointer to data pointer of correct type
  57.  * dtom(x) -    convert data pointer within mbuf to mbuf pointer (XXX)
  58.  * mtocl(x) -    convert pointer within cluster to cluster index #
  59.  * cltom(x) -    convert cluster # to ptr to beginning of cluster
  60.  */
  61. #define mtod(m,t)    ((t)((m)->m_data))
  62. #define    dtom(x)        ((struct mbuf *)((int)(x) & ~(MSIZE-1)))
  63. #define    mtocl(x)    (((u_int)(x) - (u_int)mbutl) >> MCLSHIFT)
  64. #define    cltom(x)    ((caddr_t)((u_int)mbutl + ((u_int)(x) << MCLSHIFT)))
  65.  
  66. /* header at beginning of each mbuf: */
  67. struct m_hdr {
  68.     struct    mbuf *mh_next;        /* next buffer in chain */
  69.     struct    mbuf *mh_nextpkt;    /* next chain in queue/record */
  70.     int    mh_len;            /* amount of data in this mbuf */
  71.     caddr_t    mh_data;        /* location of data */
  72.     short    mh_type;        /* type of data in this mbuf */
  73.     short    mh_flags;        /* flags; see below */
  74. };
  75.  
  76. /* record/packet header in first mbuf of chain; valid if M_PKTHDR set */
  77. struct    pkthdr {
  78.     int    len;        /* total packet length */
  79.     struct    ifnet *rcvif;    /* rcv interface */
  80. };
  81.  
  82. /* description of external storage mapped into mbuf, valid if M_EXT set */
  83. struct m_ext {
  84.     caddr_t    ext_buf;        /* start of buffer */
  85.     void    (*ext_free)();        /* free routine if not the usual */
  86.     u_int    ext_size;        /* size of buffer, for ext_free */
  87. };
  88.  
  89. struct mbuf {
  90.     struct    m_hdr m_hdr;
  91.     union {
  92.         struct {
  93.             struct    pkthdr MH_pkthdr;    /* M_PKTHDR set */
  94.             union {
  95.                 struct    m_ext MH_ext;    /* M_EXT set */
  96.                 char    MH_databuf[MHLEN];
  97.             } MH_dat;
  98.         } MH;
  99.         char    M_databuf[MLEN];        /* !M_PKTHDR, !M_EXT */
  100.     } M_dat;
  101. };
  102. #define    m_next        m_hdr.mh_next
  103. #define    m_len        m_hdr.mh_len
  104. #define    m_data        m_hdr.mh_data
  105. #define    m_type        m_hdr.mh_type
  106. #define    m_flags        m_hdr.mh_flags
  107. #define    m_nextpkt    m_hdr.mh_nextpkt
  108. #define    m_act        m_nextpkt
  109. #define    m_pkthdr    M_dat.MH.MH_pkthdr
  110. #define    m_ext        M_dat.MH.MH_dat.MH_ext
  111. #define    m_pktdat    M_dat.MH.MH_dat.MH_databuf
  112. #define    m_dat        M_dat.M_databuf
  113.  
  114. /* mbuf flags */
  115. #define    M_EXT        0x0001    /* has associated external storage */
  116. #define    M_PKTHDR    0x0002    /* start of record */
  117. #define    M_EOR        0x0004    /* end of record */
  118.  
  119. /* mbuf pkthdr flags, also in m_flags */
  120. #define    M_BCAST        0x0100    /* send/received as link-level broadcast */
  121. #define    M_MCAST        0x0200    /* send/received as link-level multicast */
  122.  
  123. /* flags copied when copying m_pkthdr */
  124. #define    M_COPYFLAGS    (M_PKTHDR|M_EOR|M_BCAST|M_MCAST)
  125.  
  126. /* mbuf types */
  127. #define    MT_FREE        0    /* should be on free list */
  128. #define    MT_DATA        1    /* dynamic (data) allocation */
  129. #define    MT_HEADER    2    /* packet header */
  130. #define    MT_SOCKET    3    /* socket structure */
  131. #define    MT_PCB        4    /* protocol control block */
  132. #define    MT_RTABLE    5    /* routing tables */
  133. #define    MT_HTABLE    6    /* IMP host tables */
  134. #define    MT_ATABLE    7    /* address resolution tables */
  135. #define    MT_SONAME    8    /* socket name */
  136. #define    MT_SOOPTS    10    /* socket options */
  137. #define    MT_FTABLE    11    /* fragment reassembly header */
  138. #define    MT_RIGHTS    12    /* access rights */
  139. #define    MT_IFADDR    13    /* interface address */
  140. #define MT_CONTROL    14    /* extra-data protocol message */
  141. #define MT_OOBDATA    15    /* expedited data  */
  142.  
  143. /* flags to m_get/MGET */
  144. #define    M_DONTWAIT    M_NOWAIT
  145. #define    M_WAIT        M_WAITOK
  146.  
  147. /*
  148.  * mbuf utility macros:
  149.  *
  150.  *    MBUFLOCK(code)
  151.  * prevents a section of code from from being interrupted by network
  152.  * drivers.
  153.  */
  154. #define    MBUFLOCK(code) \
  155.     { int ms = splimp(); \
  156.       { code } \
  157.       splx(ms); \
  158.     }
  159.  
  160. /*
  161.  * mbuf allocation/deallocation macros:
  162.  *
  163.  *    MGET(struct mbuf *m, int how, int type)
  164.  * allocates an mbuf and initializes it to contain internal data.
  165.  *
  166.  *    MGETHDR(struct mbuf *m, int how, int type)
  167.  * allocates an mbuf and initializes it to contain a packet header
  168.  * and internal data.
  169.  */
  170. #define    MGET(m, how, type) { \
  171.     MALLOC((m), struct mbuf *, MSIZE, mbtypes[type], (how)); \
  172.     if (m) { \
  173.         (m)->m_type = (type); \
  174.         MBUFLOCK(mbstat.m_mtypes[type]++;) \
  175.         (m)->m_next = (struct mbuf *)NULL; \
  176.         (m)->m_nextpkt = (struct mbuf *)NULL; \
  177.         (m)->m_data = (m)->m_dat; \
  178.         (m)->m_flags = 0; \
  179.     } else \
  180.         (m) = m_retry((how), (type)); \
  181. }
  182.  
  183. #define    MGETHDR(m, how, type) { \
  184.     MALLOC((m), struct mbuf *, MSIZE, mbtypes[type], (how)); \
  185.     if (m) { \
  186.         (m)->m_type = (type); \
  187.         MBUFLOCK(mbstat.m_mtypes[type]++;) \
  188.         (m)->m_next = (struct mbuf *)NULL; \
  189.         (m)->m_nextpkt = (struct mbuf *)NULL; \
  190.         (m)->m_data = (m)->m_pktdat; \
  191.         (m)->m_flags = M_PKTHDR; \
  192.     } else \
  193.         (m) = m_retryhdr((how), (type)); \
  194. }
  195.  
  196. /*
  197.  * Mbuf cluster macros.
  198.  * MCLALLOC(caddr_t p, int how) allocates an mbuf cluster.
  199.  * MCLGET adds such clusters to a normal mbuf;
  200.  * the flag M_EXT is set upon success.
  201.  * MCLFREE releases a reference to a cluster allocated by MCLALLOC,
  202.  * freeing the cluster if the reference count has reached 0.
  203.  *
  204.  * Normal mbuf clusters are normally treated as character arrays
  205.  * after allocation, but use the first word of the buffer as a free list
  206.  * pointer while on the free list.
  207.  */
  208. union mcluster {
  209.     union    mcluster *mcl_next;
  210.     char    mcl_buf[MCLBYTES];
  211. };
  212.  
  213. #define    MCLALLOC(p, how) \
  214.     MBUFLOCK( \
  215.       if (mclfree == 0) \
  216.         (void)m_clalloc(1, (how)); \
  217.       if ((p) = (caddr_t)mclfree) { \
  218.         ++mclrefcnt[mtocl(p)]; \
  219.         mbstat.m_clfree--; \
  220.         mclfree = ((union mcluster *)(p))->mcl_next; \
  221.       } \
  222.     )
  223.  
  224. #define    MCLGET(m, how) \
  225.     { MCLALLOC((m)->m_ext.ext_buf, (how)); \
  226.       if ((m)->m_ext.ext_buf != NULL) { \
  227.         (m)->m_data = (m)->m_ext.ext_buf; \
  228.         (m)->m_flags |= M_EXT; \
  229.         (m)->m_ext.ext_size = MCLBYTES;  \
  230.       } \
  231.     }
  232.  
  233. #define    MCLFREE(p) \
  234.     MBUFLOCK ( \
  235.       if (--mclrefcnt[mtocl(p)] == 0) { \
  236.         ((union mcluster *)(p))->mcl_next = mclfree; \
  237.         mclfree = (union mcluster *)(p); \
  238.         mbstat.m_clfree++; \
  239.       } \
  240.     )
  241.  
  242. /*
  243.  * MFREE(struct mbuf *m, struct mbuf *n)
  244.  * Free a single mbuf and associated external storage.
  245.  * Place the successor, if any, in n.
  246.  */
  247. #ifdef notyet
  248. #define    MFREE(m, n) \
  249.     { MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--;) \
  250.       if ((m)->m_flags & M_EXT) { \
  251.         if ((m)->m_ext.ext_free) \
  252.             (*((m)->m_ext.ext_free))((m)->m_ext.ext_buf, \
  253.                 (m)->m_ext.ext_size); \
  254.         else \
  255.             MCLFREE((m)->m_ext.ext_buf); \
  256.       } \
  257.       (n) = (m)->m_next; \
  258.       FREE((m), mbtypes[(m)->m_type]); \
  259.     }
  260. #else /* notyet */
  261. #define    MFREE(m, nn) \
  262.     { MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--;) \
  263.       if ((m)->m_flags & M_EXT) { \
  264.         MCLFREE((m)->m_ext.ext_buf); \
  265.       } \
  266.       (nn) = (m)->m_next; \
  267.       FREE((m), mbtypes[(m)->m_type]); \
  268.     }
  269. #endif
  270.  
  271. /*
  272.  * Copy mbuf pkthdr from from to to.
  273.  * from must have M_PKTHDR set, and to must be empty.
  274.  */
  275. #define    M_COPY_PKTHDR(to, from) { \
  276.     (to)->m_pkthdr = (from)->m_pkthdr; \
  277.     (to)->m_flags = (from)->m_flags & M_COPYFLAGS; \
  278.     (to)->m_data = (to)->m_pktdat; \
  279. }
  280.  
  281. /*
  282.  * Set the m_data pointer of a newly-allocated mbuf (m_get/MGET) to place
  283.  * an object of the specified size at the end of the mbuf, longword aligned.
  284.  */
  285. #define    M_ALIGN(m, len) \
  286.     { (m)->m_data += (MLEN - (len)) &~ (sizeof(long) - 1); }
  287. /*
  288.  * As above, for mbufs allocated with m_gethdr/MGETHDR
  289.  * or initialized by M_COPY_PKTHDR.
  290.  */
  291. #define    MH_ALIGN(m, len) \
  292.     { (m)->m_data += (MHLEN - (len)) &~ (sizeof(long) - 1); }
  293.  
  294. /*
  295.  * Compute the amount of space available
  296.  * before the current start of data in an mbuf.
  297.  */
  298. #define    M_LEADINGSPACE(m) \
  299.     ((m)->m_flags & M_EXT ? /* (m)->m_data - (m)->m_ext.ext_buf */ 0 : \
  300.         (m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \
  301.         (m)->m_data - (m)->m_dat)
  302.  
  303. /*
  304.  * Compute the amount of space available
  305.  * after the end of data in an mbuf.
  306.  */
  307. #define    M_TRAILINGSPACE(m) \
  308.     ((m)->m_flags & M_EXT ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size - \
  309.         ((m)->m_data + (m)->m_len) : \
  310.         &(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
  311.  
  312. /*
  313.  * Arrange to prepend space of size plen to mbuf m.
  314.  * If a new mbuf must be allocated, how specifies whether to wait.
  315.  * If how is M_DONTWAIT and allocation fails, the original mbuf chain
  316.  * is freed and m is set to NULL.
  317.  */
  318. #define    M_PREPEND(m, plen, how) { \
  319.     if (M_LEADINGSPACE(m) >= (plen)) { \
  320.         (m)->m_data -= (plen); \
  321.         (m)->m_len += (plen); \
  322.     } else \
  323.         (m) = m_prepend((m), (plen), (how)); \
  324.     if ((m) && (m)->m_flags & M_PKTHDR) \
  325.         (m)->m_pkthdr.len += (plen); \
  326. }
  327.  
  328. /* change mbuf to new type */
  329. #define MCHTYPE(m, t) { \
  330.     MBUFLOCK(mbstat.m_mtypes[(m)->m_type]--; mbstat.m_mtypes[t]++;) \
  331.     (m)->m_type = t;\
  332. }
  333.  
  334. /* length to m_copy to copy all */
  335. #define    M_COPYALL    1000000000
  336.  
  337. /* compatiblity with 4.3 */
  338. #define  m_copy(m, o, l)    m_copym((m), (o), (l), M_DONTWAIT)
  339.  
  340. /*
  341.  * Mbuf statistics.
  342.  */
  343. struct mbstat {
  344.     u_long    m_mbufs;    /* mbufs obtained from page pool */
  345.     u_long    m_clusters;    /* clusters obtained from page pool */
  346.     u_long    m_spare;    /* spare field */
  347.     u_long    m_clfree;    /* free clusters */
  348.     u_long    m_drops;    /* times failed to find space */
  349.     u_long    m_wait;        /* times waited for space */
  350.     u_long    m_drain;    /* times drained protocols for space */
  351.     u_short    m_mtypes[256];    /* type specific mbuf allocations */
  352. };
  353.  
  354. #ifdef    KERNEL
  355. extern    struct mbuf *mbutl;        /* virtual address of mclusters */
  356. extern    char *mclrefcnt;        /* cluster reference counts */
  357. struct    mbstat mbstat;
  358. extern    int nmbclusters;
  359. union    mcluster *mclfree;
  360. int    max_linkhdr;            /* largest link-level header */
  361. int    max_protohdr;            /* largest protocol header */
  362. int    max_hdr;            /* largest link+protocol header */
  363. int    max_datalen;            /* MHLEN - max_hdr */
  364. extern    int mbtypes[];            /* XXX */
  365.  
  366. struct    mbuf *m_copym __P((struct mbuf *, int, int, int));
  367. struct    mbuf *m_free __P((struct mbuf *));
  368. struct    mbuf *m_get __P((int, int));
  369. struct    mbuf *m_getclr __P((int, int));
  370. struct    mbuf *m_gethdr __P((int, int));
  371. struct    mbuf *m_prepend __P((struct mbuf *, int, int));
  372. struct    mbuf *m_pullup __P((struct mbuf *, int));
  373. struct    mbuf *m_retry __P((int, int));
  374. struct    mbuf *m_retryhdr __P((int, int));
  375. int    m_clalloc __P((int, int));
  376. void    m_copyback __P((struct mbuf *, int, int, caddr_t));
  377. void    m_freem __P((struct mbuf *));
  378.  
  379. #ifdef MBTYPES
  380. int mbtypes[] = {                /* XXX */
  381.     M_FREE,        /* MT_FREE    0       should be on free list */
  382.     M_MBUF,        /* MT_DATA    1       dynamic (data) allocation */
  383.     M_MBUF,        /* MT_HEADER    2       packet header */
  384.     M_SOCKET,    /* MT_SOCKET    3       socket structure */
  385.     M_PCB,        /* MT_PCB    4       protocol control block */
  386.     M_RTABLE,    /* MT_RTABLE    5       routing tables */
  387.     M_HTABLE,    /* MT_HTABLE    6       IMP host tables */
  388.     0,        /* MT_ATABLE    7       address resolution tables */
  389.     M_MBUF,        /* MT_SONAME    8       socket name */
  390.     0,        /*         9 */
  391.     M_SOOPTS,    /* MT_SOOPTS    10       socket options */
  392.     M_FTABLE,    /* MT_FTABLE    11       fragment reassembly header */
  393.     M_MBUF,        /* MT_RIGHTS    12       access rights */
  394.     M_IFADDR,    /* MT_IFADDR    13       interface address */
  395.     M_MBUF,        /* MT_CONTROL    14       extra-data protocol message */
  396.     M_MBUF,        /* MT_OOBDATA    15       expedited data  */
  397. #ifdef DATAKIT
  398.     25, 26, 27, 28, 29, 30, 31, 32        /* datakit ugliness */
  399. #endif
  400. };
  401. #endif
  402. #endif
  403.